package cn.darkhorse.device.service.impl;

import cn.darkhorse.common.constant.AuditTypeEnum;
import cn.darkhorse.common.constant.CommonConstant;
import cn.darkhorse.common.constant.WarnTypeEnum;
import cn.darkhorse.common.util.MsgUtil;
import cn.darkhorse.device.mapper.MesSpareApplyRecordsMapper;
import cn.darkhorse.device.pojo.MesRepairInfo;
import cn.darkhorse.device.pojo.MesSpareApplyRecords;
import cn.darkhorse.device.pojo.MesSpareParts;
import cn.darkhorse.device.pojo.MesSpareType;
import cn.darkhorse.device.service.*;
import cn.darkhorse.device.vo.MesSpareApplyRecordsVO;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * <p>
 * 备件申请记录表 服务实现类
 * </p>
 *
 * @author maoguanjun
 * @since 2022-11-11
 */
@Service
public class MesSpareApplyRecordsServiceImpl extends ServiceImpl<MesSpareApplyRecordsMapper, MesSpareApplyRecords> implements MesSpareApplyRecordsService {

    @Resource
    private  MesSpareApplyRecordsMapper mesSpareApplyRecordsMapper;
    @Resource
    private MesSpareTypeService mesSpareTypeService;
    @Resource
    private MesSparePartsService mesSparePartsService;
    @Resource
    private MesRepairInfoService mesRepairInfoService;
    @Resource
    private MesMsgAuditService mesMsgAuditService;
    /**
     * 列表
     *
     * @param deptId
     * @param spareName
     * @return
     */
    @Override
    public List<MesSpareApplyRecordsVO> listAll(Long deptId, String spareName,Long repairId,String orderType) {
        if(StringUtils.isBlank(orderType)){
            orderType=CommonConstant.ORDER_TYPE_DESC;
        }
        List<MesSpareApplyRecordsVO> mesSpareApplyRecordsVOS = mesSpareApplyRecordsMapper.listAll(deptId, spareName,repairId,orderType);
        return mesSpareApplyRecordsVOS;
    }

    /**
     * 查看
     *
     * @param id
     * @return
     */
    @Override
    public MesSpareApplyRecordsVO view(Long id) {
        MesSpareApplyRecordsVO vo=new MesSpareApplyRecordsVO();
        MesSpareApplyRecords records=getById(id);
        if(null!=records){
            BeanUtils.copyProperties(records,vo);
            MesSpareType type=mesSpareTypeService.getById(records.getSpareType());
            vo.setTypeName(type.getName());
        }else{
            throw new ServiceException("该业务单据已删除!");
        }
        return vo;
    }

    /**
     * 保存
     *
     * @param mesSpareApplyRecords
     * @return
     */
    @Override
    public boolean saveSpareApplyRecords(MesSpareApplyRecords mesSpareApplyRecords,Integer type) {
        BigDecimal oldNum=BigDecimal.ZERO;
        if(null!=mesSpareApplyRecords.getId()){
            if(!allowModify(mesSpareApplyRecords.getId())){
                throw new ServiceException("只有待审状态可以修改！");
            }
            MesSpareApplyRecords byId = getById(mesSpareApplyRecords.getId());
            oldNum=null!=byId?byId.getApplyNum():BigDecimal.ZERO;

        }
        mesSparePartsService.upInventory(mesSpareApplyRecords.getSpareId(),mesSpareApplyRecords.getApplyNum(),oldNum,false,mesSpareApplyRecords.getApplyType());
        mesSpareApplyRecords.setApplyType(type);
        boolean b = saveOrUpdate(mesSpareApplyRecords);
        //消息提醒
        sendWarnMsg(mesSpareApplyRecords.getSpareId(),mesSpareApplyRecords.getId(),mesSpareApplyRecords.getApplyNum());
        return b;
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    @Override
    @Transactional
    public boolean delete(Long id) {
        if(!allowDelete(id)){
            throw new ServiceException("只有手动添加的申请单可以删除！");
        }
        if(!allowModify(id)){
            throw new ServiceException("只有待审状态可以删除！");
        }
        MesSpareApplyRecords byId = getById(id);
        mesSparePartsService.upInventory(byId.getSpareId(),byId.getApplyNum(),BigDecimal.ZERO,true,byId.getApplyType());
        return removeById(id);
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteByRepairId(Long id) {
        LambdaQueryWrapper<MesSpareApplyRecords> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(MesSpareApplyRecords::getRepairId,id);
        wrapper.eq(MesSpareApplyRecords::getApplyType,CommonConstant.SPARE_APPLY_TYPE_REPAIR);
        MesSpareApplyRecords records=getOne(wrapper);
        if(null!=records){
            if(!CommonConstant.AUDIT_STATUS_PENDING_TRIAL.equals(records.getAuditStatus())){
                throw new ServiceException("备件申请已审核，请先弃审后删除！");
            }
            mesSparePartsService.upInventory(records.getSpareId(),records.getApplyNum(),BigDecimal.ZERO,false,records.getApplyType());
        }
        //删除未审已删除消息
        mesMsgAuditService.removeMsg(id,AuditTypeEnum.SPARE_PARTS_APPLY.getType());
        return removeById(id);
    }

    /**
     * 提交
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean submit(Long id) {
        MesSpareApplyRecords info=getById(id);
        if(null!=info){
            info.setAuditStatus(CommonConstant.AUDIT_STATUS_UNDER_REVIEWED);
            //发送审核消息
            mesMsgAuditService.sendAuditMsg(AuditTypeEnum.SPARE_PARTS_APPLY.getTypeName(), info.getId(), null);
            return updateById(info);
        }
        return false;
    }

    /**
     * 审核
     *
     * @param id
     * @param approver
     * @param approveTime
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean audit(Long id, Long approver, String approveTime,Integer auditStatus) {
        MesSpareApplyRecords info=getById(id);
        if(null!=info){
            if(auditStatus.equals(CommonConstant.AUDIT_STATUS_REVIEWED)){
                info.setApprover(approver);
                info.setApproveTime(LocalDateTime.parse(approveTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            }else {
                info.setApprover(approver);
                info.setApproveTime(LocalDateTime.parse(approveTime, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            }
            info.setAuditStatus(auditStatus);
            //更新审核通知
            mesMsgAuditService.upAuditMsg(id,approver,approveTime,auditStatus,AuditTypeEnum.SPARE_PARTS_APPLY.getType());
            return updateById(info);
        }
        return false;
    }

    /**
     * 弃审
     *
     * @param id
     * @return
     */
    @Override
    public boolean waiver(Long id) {
       if(!allowWaiver(id)){
            throw new ServiceException("不允许弃审！");
        }
        MesSpareApplyRecords info=getById(id);
        if(null!=info){
            info.setAuditStatus(CommonConstant.AUDIT_STATUS_PENDING_TRIAL);
            return updateById(info);
        }
        return false;
    }

    /**
     * 是否允许修改
     * @param id
     * @return
     */
    boolean  allowModify(Long id) {
        MesSpareApplyRecords info = getById(id);
        if (null != info) {
            if (CommonConstant.AUDIT_STATUS_PENDING_TRIAL.equals(info.getAuditStatus())) {
                return true;
            }
        }
        return false;
    }
    boolean  allowDelete(Long id) {
        MesSpareApplyRecords info = getById(id);
        if (null != info) {
            if (CommonConstant.SPARE_APPLY_TYPE_ADD.equals(info.getApplyType())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 是否能够弃审
     * @param id
     * @return
     */
    boolean  allowWaiver(Long id) {
        MesSpareApplyRecords info = getById(id);
        if (null != info) {
            if (CommonConstant.SPARE_APPLY_TYPE_ADD.equals(info.getApplyType())) {
                return true;
            //维修单
            }else if(CommonConstant.SPARE_APPLY_TYPE_REPAIR.equals(info.getApplyType())){
                MesRepairInfo repairInfo=mesRepairInfoService.getById(info.getRepairId());
                if(null!=repairInfo){
                    if (CommonConstant.AUDIT_STATUS_PENDING_TRIAL.equals(repairInfo.getAuditStatus())) {
                        return true;
                    }else{
                        throw new ServiceException("维修单不是未审状态，不允许弃审！");
                    }
                }
            }
        }
        return false;
    }

    /**
     * 发送消息信息
     * @param spareId
     * @param businessId
     * @param applyNum
     */
    @Override
    public void sendWarnMsg(Long spareId, Long businessId, BigDecimal applyNum){
        MesSpareParts mesSpareParts=mesSparePartsService.getById(spareId);
        //本次提醒前库存在安全数量之上 修改为只要库存小于安全数量就提醒
        //BigDecimal flag=mesSpareParts.getInventory().add(applyNum).subtract(mesSpareParts.getForewarnInventory());
        BigDecimal flag=mesSpareParts.getInventory().subtract(mesSpareParts.getForewarnInventory());
        //if(flag.compareTo(BigDecimal.ZERO)>=0&&flag.subtract(applyNum).compareTo(BigDecimal.ZERO)==-1){
        if(flag.compareTo(BigDecimal.ZERO)==-1){
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("type", WarnTypeEnum.SPARE_PARTS.getTypeName());
            jsonObject.put("businessId",spareId);
            jsonObject.put("applyRecordId",businessId);
            jsonObject.put("businessDate", LocalDateTimeUtil.formatNormal(LocalDateTime.now()));
            jsonObject.put("instantInventory",mesSpareParts.getInventory());
            MsgUtil.sendWaringMsg(jsonObject.toJSONString());
        }
    }
}
